using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace My.IdlConverter.Core.Types
{
    internal class TypeRecognizer
    {
        public const string StlmapRegex = @"std\:\:map\<.{3,8},.{3,8}\>";
        public const string StlvectorRegex = @"std\:\:vector\<.{3,8}\>";
        public const string StllistRegex = @"std\:\:list\<.{3,8}\>";

        public static bool ExistStlMap(string source)
        {
            return Regex.IsMatch(source, StlmapRegex);
        }

        public static bool ExistStlVector(string source)
        {
            return Regex.IsMatch(source, StlvectorRegex);
        }

        public static bool ExistStlList(string source)
        {
            return Regex.IsMatch(source, StllistRegex);
        }

        public static bool ExistStlTypes(string source)
        {
            return (ExistStlMap(source) || ExistStlList(source) || ExistStlVector(source));
        }

        private struct ReplaceRelation
        {
            public string Origin;
            public string Substitute;
            public ReplaceRelation(string orgin, string sub)
            {
                Origin = orgin;
                Substitute = sub;
            }
        }

        public static StringCollection GetStlTypeEntries(string methodString)
        {
            const string STL_MAP_SUBSTITUTE = "%map%";
            const string STL_LIST_SUBSTITUTE = "%list%";
            const string STL_VECTOR_SUBSTITUTE = "%vector%";

            string tmpMehtodString = methodString;

            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("({0})|", StllistRegex);
            sb.AppendFormat("({0})|", StlvectorRegex);
            sb.AppendFormat("({0})|", StlmapRegex);
            if (sb[sb.Length - 1] == '|')
                sb.Remove(sb.Length - 1, 1);

            IList<ReplaceRelation> relations = new List<ReplaceRelation>();

            MatchCollection matchCol = Regex.Matches(methodString, @sb.ToString());
            StringCollection types = new StringCollection();
            foreach (Match nextMatch in matchCol)
            {
                string matchValue = nextMatch.Value;
                if (ExistStlList(matchValue))
                {
                    tmpMehtodString = tmpMehtodString.Replace(matchValue, STL_LIST_SUBSTITUTE);
                    relations.Add(new ReplaceRelation(matchValue, STL_LIST_SUBSTITUTE));
                }
                else if (ExistStlMap(matchValue))
                {
                    tmpMehtodString = tmpMehtodString.Replace(matchValue, STL_MAP_SUBSTITUTE);
                    relations.Add(new ReplaceRelation(matchValue, STL_MAP_SUBSTITUTE));
                }
                else if (ExistStlVector(matchValue))
                {
                    tmpMehtodString = tmpMehtodString.Replace(matchValue, STL_VECTOR_SUBSTITUTE);
                    relations.Add(new ReplaceRelation(matchValue, STL_VECTOR_SUBSTITUTE));
                }
                else
                {
                    Debug.Assert(false);
                }
            }
            string[] entries = tmpMehtodString.Split(new char[] { ','},StringSplitOptions.RemoveEmptyEntries);
            foreach (string nextEntry in entries)
            {
                foreach (ReplaceRelation nextRelation in relations)
                {
                    if (nextEntry.IndexOf(nextRelation.Substitute) != -1)
                    {
                        types.Add(nextEntry.Replace(nextRelation.Substitute,nextRelation.Origin));
                    }
                }
            }

            return types;
        }
    }
}

